#include <stdlib.h>
#include <stdint.h>

#include <common/macro/build.h>
#include <common/datatype.h>
#include <common/predicate.h>

API_FILELOCAL int verify(void *datatype_args, char *data, size_t size) {
	return (size == sizeof(double));
}

API_FILELOCAL void *predicate_generic_compile(void *datatype_args, size_t *argsizes, char **arguments, int argc) {
	double *tmp;

	if (argsizes[0] != sizeof(double))
		return NULL;

	tmp = malloc(sizeof(*tmp));
	*tmp = *((double*)arguments[0]);
	return tmp;
}

API_FILELOCAL void predicate_generic_release(void *predicate_arg) {
	if (predicate_arg == NULL) return;

	free(predicate_arg);
}

API_FILELOCAL int predicate_eq_execute(char *data, size_t size, void *predicate_arg, void **internal) {
	return ((*(double*)data) == (*(double*)predicate_arg));
}

API_FILELOCAL int predicate_le_execute(char *data, size_t size, void *predicate_arg, void **internal) {
	return ((*(double*)data) <= (*(double*)predicate_arg));
}

API_FILELOCAL int predicate_ge_execute(char *data, size_t size, void *predicate_arg, void **internal) {
	return ((*(double*)data) >= (*(double*)predicate_arg));
}

API_FILELOCAL int predicate_lt_execute(char *data, size_t size, void *predicate_arg, void **internal) {
	return ((*(double*)data) < (*(double*)predicate_arg));
}

API_FILELOCAL int predicate_gt_execute(char *data, size_t size, void *predicate_arg, void **internal) {
	return ((*(double*)data) > (*(double*)predicate_arg));
}

API_FILELOCAL predicate_t predicates[] = {
	{"eq", 1, 1, predicate_generic_compile, predicate_eq_execute, predicate_generic_release},
	{"le", 1, 1, predicate_generic_compile, predicate_le_execute, predicate_generic_release},
	{"ge", 1, 1, predicate_generic_compile, predicate_ge_execute, predicate_generic_release},
	{"lt", 1, 1, predicate_generic_compile, predicate_lt_execute, predicate_generic_release},
	{"gt", 1, 1, predicate_generic_compile, predicate_gt_execute, predicate_generic_release},
};

API_LIBLOCAL datatype_t dt_float64 = {
	"float64",

	-1, -1,
	NULL, NULL, /* No arguments, ergo no parsing/destruction. */

	verify,
	NULL, /* Nothing to destroy. */

	predicates,
};
